<script lang="ts" setup>
import { computed, ref, watch, onBeforeUnmount, onMounted } from 'vue';
import { ElInput, ElMessageBox } from 'element-plus';
import { useRoute, useRouter } from 'vue-router';
import { commands, events } from '../../bindings';
import SaveLocationDrawer from '../../components/SaveLocationDrawer.vue';
import type { Game, Snapshot, Device } from '../../bindings';
import { $t } from '../../i18n';
import { error, info } from '@tauri-apps/plugin-log';

const { showInfo, showError, showSuccess } = useNotification();
const { config, refreshConfig, saveConfig } = useConfig();
const { withLoading } = useGlobalLoading();
const router = useRouter();
const route = useRoute();
const top_buttons = [
  { text: $t('manage.create_new_save'), method: create_new_save },
  { text: $t('manage.load_latest_save'), method: load_latest_save },
  { text: $t('manage.launch_game'), method: launch_game },
  { text: $t('manage.open_backup_folder'), method: open_backup_folder },
  {
    text: $t('manage.show_drawer'),
    method: () => {
      drawer.value = !drawer.value;
    },
  },
  { text: $t('manage.set_quick_backup'), method: set_quick_backup },
];

const search = ref(''); // 搜索时使用的字符串
const drawer = ref(false); // 是否显示存档位置侧栏

const table_data = ref([
  {
    date: '',
    describe: $t('manage.error_info'),
    path: '',
  },
]);

const game: Ref<Game> = ref({
  name: '',
  save_paths: [],
  game_paths: {},
});

// 当前设备信息
const currentDevice = ref<Device | null>(null);

// 获取当前设备信息
async function fetchCurrentDevice() {
  try {
    const result = await commands.getCurrentDeviceInfo();
    if (result.status === 'ok') {
      currentDevice.value = result.data;
    } else {
      showError({ message: result.error });
    }
  } catch (e) {
    error(`Error getting current device info: ${e}`);
    showError({ message: $t('error.get_device_info_failed') });
  }
}

// 在组件挂载时获取当前设备信息
fetchCurrentDevice();

const describe = ref('');
let backup_button_time_limit = true; // 两次备份时间间隔1秒
let backup_button_backup_limit = true; // 上次没备份好禁止再备份或读取
let apply_button_apply_limit = true; // 上次未恢复好禁止读取或备份

// 批量操作记录列表
const selected_game_snapshots: Ref<Snapshot[]> = ref([]);

let stopQuickActionListener: (() => void) | null = null;

onMounted(async () => {
  try {
    stopQuickActionListener = await events.quickActionCompleted.listen(async (event) => {
      const payload = event.payload;
      if (
        payload.status === 'Success' &&
        payload.operation === 'Backup' &&
        payload.game_name &&
        payload.game_name === game.value.name
      ) {
        await refresh_backups_info();
      }
    });
  } catch (e) {
    error(`Failed to listen quick action events: ${e}`);
  }
});

onBeforeUnmount(() => {
  if (stopQuickActionListener) {
    stopQuickActionListener();
    stopQuickActionListener = null;
  }
});

// 格式化文件大小显示
function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function on_selection_change(val: Snapshot[]) {
  selected_game_snapshots.value = val;
}
async function batch_delete() {
  try {
    const result = await ElMessageBox.prompt($t('manage.batch_delete_prompt'), $t('home.hint'), {
      confirmButtonText: $t('manage.confirm'),
      cancelButtonText: $t('manage.cancel'),
      inputPattern: /yes/,
      inputErrorMessage: $t('manage.invalid_input_error'),
    });

    if (result.value === 'yes') {
      for (const item of selected_game_snapshots.value) {
        await del_save(item.date);
      }
    } else {
      showInfo({ message: $t('manage.invalid_input_error') });
    }
  } catch {
    showError({ message: $t('manage.operation_canceled') });
  }
}

// Init game info
watch(
  () => route.params.name,
  (newValue) => {
    if (!newValue) {
      return;
    }
    const name = newValue;
    game.value = config.value.games.find((x) => x.name == name) as Game;
    refresh_backups_info();
    // 检查当前设备的存档路径是否为空
    checkCurrentDeviceSavePaths();
  },
  { immediate: true }
);

async function refresh_backups_info() {
  const result = await commands.getGameSnapshotsInfo(game.value);
  if (result.status === 'error') {
    showError({ message: result.error });
  } else {
    table_data.value = result.data.backups;
  }
}

async function send_save_to_background() {
  showInfo({ message: $t('manage.wait_for_prompt_hint') });
  if (!backup_button_time_limit) {
    showError({ message: $t('manage.save_too_fast_error') });
    return;
  }
  if (!backup_button_backup_limit) {
    showError({ message: $t('manage.last_backup_unfinished_error') });
    return;
  }
  if (!apply_button_apply_limit) {
    showError({ message: $t('manage.last_overwrite_unfinished_error') });
    return;
  }
  backup_button_time_limit = false;
  backup_button_backup_limit = false;

  await withLoading(async () => {
    const result = await commands.createSnapshot(game.value, describe.value);
    if (result.status === 'error') {
      showError({ message: result.error });
    } else {
      showSuccess({ message: $t('manage.backup_success') });
    }
  }, $t('manage.creating_backup'));
  backup_button_backup_limit = true;
  refresh_backups_info();

  describe.value = '';
  setTimeout(() => {
    backup_button_time_limit = true;
  }, 1000);
}

async function create_new_save() {
  if (config.value.settings.prompt_when_not_described && !describe.value) {
    try {
      await ElMessageBox.confirm($t('manage.no_description_warning'), $t('manage.warning'), {
        confirmButtonText: $t('manage.confirm_save'),
        cancelButtonText: $t('manage.cancel'),
        type: 'warning',
      });
      send_save_to_background();
    } catch {
      info('User cancelled the save operation.');
    }
  } else {
    send_save_to_background();
  }
}

async function launch_game() {
  // 获取当前设备的游戏路径
  let gamePath = '';
  if (currentDevice.value && game.value.game_paths) {
    gamePath = game.value.game_paths[currentDevice.value.id] || '';
  }

  if (!gamePath) {
    showError({ message: $t('manage.no_launch_path_error') });
    return;
  } else {
    const result = await commands.openFileOrFolder(gamePath);
    if (result.status === 'error') {
      showError({ message: result.error });
    }
  }
}

async function del_save(date: string) {
  try {
    await commands.deleteSnapshot(game.value, date);
    refresh_backups_info();
    showSuccess({ message: $t('manage.delete_success') });
  } catch (e) {
    error(`Failed to delete snapshot: ${e}`);
    showError({ message: $t('error.delete_snapshot_failed') });
  }
}

async function apply_save(date: string) {
  showInfo({ message: $t('manage.wait_for_prompt_hint') });

  if (!apply_button_apply_limit) {
    showError({ message: $t('manage.last_overwrite_unfinished_error') });
    return;
  }
  if (!backup_button_backup_limit) {
    showError({ message: $t('manage.last_backup_unfinished_error') });
    return;
  }
  apply_button_apply_limit = false;
  await withLoading(async () => {
    const result = await commands.restoreSnapshot(game.value, date);
    if (result.status === 'error') {
      showError({ message: $t('manage.recover_failed') });
    } else {
      showSuccess({ message: $t('manage.recover_success') });
    }
  }, $t('manage.restoring_backup'));
  apply_button_apply_limit = true;
  refresh_backups_info();
}

async function change_describe(date: string) {
  try {
    const { value } = await ElMessageBox.prompt(
      $t('manage.input_description_prompt'),
      $t('manage.change_description'),
      {
        confirmButtonText: $t('manage.confirm'),
        cancelButtonText: $t('manage.cancel'),
        inputValue: table_data.value.find((x) => x.date == date)?.describe,
      }
    );
    const result = await commands.setSnapshotDescription(game.value, date, value);
    if (result.status === 'error') {
      // TODO: 增加文本
      showError({ message: $t('manage.change_description_failed') });
    }
    refresh_backups_info();
    showSuccess({ message: $t('manage.change_description_success') });
  } catch {
    showInfo({ message: $t('manage.operation_canceled') });
  }
}

function load_latest_save() {
  // 数组是正序的，最后一个是最新的，而展示用的filter_table是倒序的
  const lastIndex = table_data.value.length - 1;
  const lastBackup = lastIndex >= 0 ? table_data.value[lastIndex] : undefined;

  if (lastBackup?.date) {
    apply_save(lastBackup.date);
  } else {
    showError({ message: $t('manage.no_backup_error') });
  }
}

async function del_cur() {
  try {
    const { value } = await ElMessageBox.prompt($t('manage.delete_prompt'), $t('home.hint'), {
      confirmButtonText: $t('manage.confirm'),
      cancelButtonText: $t('manage.cancel'),
      inputPattern: /yes/,
      inputErrorMessage: $t('manage.invalid_input_error'),
    });

    if (value === 'yes') {
      const result = await commands.deleteGame(game.value);
      if (result.status === 'error') {
        showError({ message: $t('error.delete_game_failed') });
      }
      await refreshConfig();
      router.back();
    } else {
      showInfo({ message: $t('manage.invalid_input_error') });
    }
  } catch {
    showInfo({ message: $t('manage.operation_canceled') });
  }
}

async function open_backup_folder() {
  const result = await commands.openBackupFolder(game.value);
  if (result.status === 'error') {
    showError({ message: $t('error.open_backup_folder_failed') });
  }
}

// 设置快速备份，由快捷键和tray触发备份和恢复
async function set_quick_backup() {
  const result = await commands.setQuickBackupGame(game.value);
  if (result.status === 'error') {
    showError({ message: $t('manage.set_quick_backup_failed') });
    return;
  }
  showSuccess({ message: $t('manage.set_quick_backup_success') });
}

// 处理抽屉组件保存游戏路径的事件
async function on_drawer_save_changes(updatedGame: Game) {
  // 更新游戏信息（包括存档路径和启动路径）
  game.value = updatedGame;

  // 保存到配置
  const index = config.value.games.findIndex((g) => g.name === game.value.name);
  if (index !== -1) {
    config.value.games[index] = game.value;
    saveConfig()
      .then(() => {
        showSuccess({ message: $t('manage.save_paths_updated') });
      })
      .catch((e) => {
        error(`Error saving config: ${e}`);
        showError({ message: $t('error.save_config_failed') });
      });
  } else {
    showError({ message: $t('error.game_not_found') });
  }

  // 关闭侧栏
  drawer.value = false;
}

const filter_table = computed(() => {
  return table_data.value
    .filter(
      (data) =>
        !search.value || data.describe.includes(search.value) || data.date.includes(search.value)
    )
    .reverse();
});

// 检查当前设备的存档路径是否为空
async function checkCurrentDeviceSavePaths() {
  await fetchCurrentDevice();
  if (!currentDevice.value || !game.value || !game.value.save_paths) return;

  // 检查当前设备的存档路径是否全部为空
  const deviceId = currentDevice.value.id;
  const allPathsEmpty = game.value.save_paths.every(
    (unit) => !unit.paths || !unit.paths[deviceId] || unit.paths[deviceId].trim() === ''
  );

  if (!allPathsEmpty) return; // 如果有路径不为空，直接返回

  // 收集所有有效的设备ID（有存档路径的设备）
  const devicesWithPaths = new Set<string>();
  game.value.save_paths.forEach((unit) => {
    if (unit.paths) {
      Object.entries(unit.paths).forEach(([id, path]) => {
        if (id !== deviceId && path && path.trim() !== '') {
          devicesWithPaths.add(id);
        }
      });
    }
  });

  if (devicesWithPaths.size === 0) return; // 如果没有其他设备有路径，直接返回

  try {
    // 询问用户是否要复制其他设备的存档路径
    const confirmResult = await ElMessageBox.confirm(
      $t('manage.empty_paths_prompt'),
      $t('manage.empty_paths_title'),
      {
        confirmButtonText: $t('manage.copy_from_device'),
        cancelButtonText: $t('manage.keep_empty'),
        type: 'info',
        closeOnClickModal: false,
        closeOnPressEscape: false,
      }
    );

    if (confirmResult !== 'confirm') return;

    // 准备设备选择列表
    const deviceOptions = Array.from(devicesWithPaths).map((id) => ({
      value: id,
      label: id.substring(0, 8) + '...',
    }));

    // 如果只有一个设备，直接使用它
    if (deviceOptions.length === 1) {
      const singleOption = deviceOptions.at(0);
      if (singleOption) {
        await copyPathsFromDevice(singleOption.value);
        return;
      }
    }

    // 让用户从多个设备中选择
    try {
      // 显示设备列表供用户选择
      const items = deviceOptions
        .map((d, index) => `${index + 1}. ${d.label} (${d.value})`)
        .join('\n');

      const { value } = await ElMessageBox.prompt(
        `${$t('manage.select_device_prompt')}\n\n${items}\n\n${$t('manage.enter_device_id')}:`,
        $t('manage.select_device_title'),
        {
          confirmButtonText: $t('manage.confirm'),
          cancelButtonText: $t('manage.cancel'),
        }
      );

      // 查找匹配的设备ID
      const selectedDevice = deviceOptions.find(
        (d) => d.value === value || d.value.startsWith(value) || d.label.includes(value)
      );

      if (selectedDevice) {
        await copyPathsFromDevice(selectedDevice.value);
      }
    } catch {
      // 用户取消选择，不执行任何操作
    }
  } catch {
    // 用户取消初始确认，不执行任何操作
  }
}

// 从指定设备复制存档路径到当前设备
async function copyPathsFromDevice(sourceDeviceId: string) {
  if (!currentDevice.value || !game.value) return;

  const targetDeviceId = currentDevice.value.id;
  let updated = false;

  // 复制存档路径
  if (game.value.save_paths) {
    game.value.save_paths.forEach((unit) => {
      if (unit.paths?.[sourceDeviceId]?.trim()) {
        if (!unit.paths[targetDeviceId] || !unit.paths[targetDeviceId].trim()) {
          if (!unit.paths) unit.paths = {};
          unit.paths[targetDeviceId] = unit.paths[sourceDeviceId];
          updated = true;
        }
      }
    });
  }

  // 复制游戏启动路径
  if (
    game.value.game_paths?.[sourceDeviceId]?.trim() &&
    (!game.value.game_paths[targetDeviceId] || !game.value.game_paths[targetDeviceId].trim())
  ) {
    if (!game.value.game_paths) game.value.game_paths = {};
    game.value.game_paths[targetDeviceId] = game.value.game_paths[sourceDeviceId];
    updated = true;
  }

  // 如果有更新，保存配置
  if (updated) {
    const index = config.value.games.findIndex((g) => g.name === game.value.name);
    if (index !== -1) {
      config.value.games[index] = game.value;
      try {
        await saveConfig();
        showSuccess({ message: $t('manage.paths_copied_success') });
        // 打开侧栏让用户查看和编辑复制的路径
        drawer.value = true;
      } catch (e) {
        error(`Error saving config: ${e}`);
        showError({ message: $t('error.save_config_failed') });
      }
    }
  }
}
</script>

<template>
  <div class="manage-container">
    <!-- 下面是顶栏部分 -->
    <el-card class="manage-top-bar">
      <div class="button-bar">
        <template v-for="button in top_buttons" :key="button.text">
          <el-button type="primary" round @click="button.method">
            {{ button.text }}
          </el-button>
        </template>

        <!-- TODO: 移除该功能 -->
        <!-- <el-button v-if="showEditButton" type="danger" round @click="edit_cur()">
                    {{ $t('manage.change_info') }}
                </el-button> -->
        <el-button type="danger" round @click="del_cur()">
          {{ $t('manage.delete_save_manage') }}
        </el-button>
        <el-button
          v-if="selected_game_snapshots.length > 0"
          type="danger"
          round
          @click="batch_delete()"
        >
          {{ $t('manage.batch_delete') }}
        </el-button>
      </div>
      <!-- 下面是当前存档描述信息 -->
      <el-form @submit.prevent="create_new_save">
        <el-input v-model="describe" :placeholder="$t('manage.input_description_prompt')">
          <template #prepend>{{ game.name + $t('manage.new_save_of') }} </template>
        </el-input>
      </el-form>
    </el-card>
    <!-- 下面是主体部分 -->
    <el-card class="saves-container">
      <!-- 存档应当用点击展开+内部表格的方式来展示 -->
      <!-- 这里应该有添加新存档按钮，按下后选择标题和描述进行存档 -->
      <el-table :data="filter_table" style="width: 100%" @selection-change="on_selection_change">
        <el-table-column type="selection" width="55" />
        <el-table-column :label="$t('manage.save_date')" prop="date" width="200px" sortable />
        <el-table-column :label="$t('manage.description')" prop="describe" />
        <el-table-column :label="$t('manage.size')" width="120px">
          <template #default="scope">
            <span v-if="scope.row.size && scope.row.size > 0">
              {{ formatFileSize(scope.row.size) }}
            </span>
            <span v-else class="text-muted">
              {{ $t('manage.size_not_available') }}
            </span>
          </template>
        </el-table-column>
        <el-table-column align="right">
          <template #header>
            <!-- 搜索 -->
            <el-input
              v-model="search"
              size="small"
              :placeholder="$t('manage.input_description_search_prompt')"
              clearable
            />
          </template>
          <template #default="scope">
            <!-- scope.$index和scope.row可以被使用 -->
            <el-popconfirm
              :title="$t('manage.confirm_overwrite_prompt')"
              @confirm="apply_save(scope.row.date)"
            >
              <template #reference>
                <el-button size="small"> {{ $t('manage.apply') }} </el-button>
              </template>
            </el-popconfirm>
            <el-button size="small" @click="change_describe(scope.row.date)">
              {{ $t('manage.change_describe') }}
            </el-button>
            <el-popconfirm
              :title="$t('manage.confirm_delete_prompt')"
              @confirm="del_save(scope.row.date)"
            >
              <template #reference>
                <el-button size="small" type="danger"> {{ $t('manage.delete') }} </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 下面是存档所在位置侧栏部分 -->
    <save-location-drawer
      v-if="game"
      v-model="drawer"
      :game="game"
      @closed="drawer = false"
      @save-changes="on_drawer_save_changes"
    />
  </div>
</template>

<style scoped>
.el-button {
  margin-left: 10px !important;
  margin-top: 5px;
}

.manage-top-bar {
  width: 98%;
  padding-right: 10px;
  padding-left: 10px;
  margin: auto auto 5px;

  display: flex;
  border-radius: 10px;
  align-items: center;
  color: aliceblue;
}

.manage-top-bar .el-input {
  margin-top: 15px;
}

.saves-container {
  margin: auto;
}
</style>
